package com.totem.product.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.totem.admin.mapper.TAppConfigItemMapper;
import com.totem.admin.mapper.TAppConfigMapper;
import com.totem.admin.model.TAppConfigItem;
import com.totem.base.constants.ErrorCode;
import com.totem.base.enums.*;
import com.totem.base.exception.BaseException;
import com.totem.base.mybatis.UserIdContext;
import com.totem.customer.mapper.TCustomerMapper;
import com.totem.order.mapper.TWalletMapper;
import com.totem.order.model.TWallets;
import com.totem.product.mapper.TSubscribeMapper;
import com.totem.product.model.TSubscribe;
import com.totem.product.service.ITSubscribeService;
import com.totem.product.vo.SubscribeVO;
import com.totem.startup.InitialGlobalConfig;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

@Slf4j
@Service
public class TSubscribeServiceImpl  extends ServiceImpl<TSubscribeMapper, TSubscribe> implements ITSubscribeService {
    @Autowired
    private TAppConfigMapper tAppConfigMapper;
    @Autowired
    private TAppConfigItemMapper tAppConfigItemMapper;
    @Autowired
    private TCustomerMapper customerMapper;
    @Autowired
    private TWalletMapper tWalletMapper;
    @Override
    public boolean initData() {
        BigDecimal lowest = new BigDecimal(100);
        TSubscribe usdo1 = TSubscribe.builder()
                .subscribeName(SubscribeNameEnum.SUBSCRIBE_1.getCode())
                .subscribeNameCn(SubscribeNameEnum.SUBSCRIBE_1.getCn())
                .subscribeDays(SubscribeDaysEnum.SUBSCRIBE_1.getCode())
                .subscribeLevel(SubscribeLevelEnum.NORMAL.getCode())
                .dailyRateReturn(new BigDecimal("0.006"))
                .threshold(lowest)
                .build();
        TSubscribe usdo7 = TSubscribe.builder()
                .subscribeName(SubscribeNameEnum.SUBSCRIBE_7.getCode())
                .subscribeNameCn(SubscribeNameEnum.SUBSCRIBE_7.getCn())
                .subscribeDays(SubscribeDaysEnum.SUBSCRIBE_7.getCode())
                .subscribeLevel(SubscribeLevelEnum.NORMAL.getCode())
                .dailyRateReturn(new BigDecimal("0.008"))
                .threshold(lowest)
                .build();
        TSubscribe usdo15 = TSubscribe.builder()
                .subscribeName(SubscribeNameEnum.SUBSCRIBE_15.getCode())
                .subscribeNameCn(SubscribeNameEnum.SUBSCRIBE_15.getCn())
                .subscribeDays(SubscribeDaysEnum.SUBSCRIBE_15.getCode())
                .subscribeLevel(SubscribeLevelEnum.NORMAL.getCode())
                .dailyRateReturn(new BigDecimal("0.01"))
                .threshold(lowest)
                .build();
        TSubscribe usdo30 = TSubscribe.builder()
                .subscribeName(SubscribeNameEnum.SUBSCRIBE_30.getCode())
                .subscribeNameCn(SubscribeNameEnum.SUBSCRIBE_30.getCn())
                .subscribeDays(SubscribeDaysEnum.SUBSCRIBE_30.getCode())
                .subscribeLevel(SubscribeLevelEnum.NORMAL.getCode())
                .dailyRateReturn(new BigDecimal("0.012"))
                .threshold(lowest)
                .build();
        TSubscribe talent = TSubscribe.builder()
                .subscribeName(SubscribeNameEnum.SUBSCRIBE_DALENT.getCode())
                .subscribeNameCn(SubscribeNameEnum.SUBSCRIBE_DALENT.getCn())
                .subscribeDays(SubscribeDaysEnum.SUBSCRIBE_30.getCode())
                .subscribeLevel(SubscribeLevelEnum.TALENT.getCode())
                .dailyRateReturn(new BigDecimal("0.012"))
                .threshold(new BigDecimal(1500))
                .build();
        TSubscribe king = TSubscribe.builder()
                .subscribeName(SubscribeNameEnum.SUBSCRIBE_KING.getCode())
                .subscribeNameCn(SubscribeNameEnum.SUBSCRIBE_KING.getCn())
                .subscribeDays(SubscribeDaysEnum.SUBSCRIBE_30.getCode())
                .subscribeLevel(SubscribeLevelEnum.KING.getCode())
                .dailyRateReturn(new BigDecimal("0.012"))
                .threshold(new BigDecimal(3000))
                .build();
        TSubscribe supreme = TSubscribe.builder()
                .subscribeName(SubscribeNameEnum.SUBSCRIBE_SUPREME.getCode())
                .subscribeNameCn(SubscribeNameEnum.SUBSCRIBE_SUPREME.getCn())
                .subscribeDays(SubscribeDaysEnum.SUBSCRIBE_30.getCode())
                .subscribeLevel(SubscribeLevelEnum.SUPREME.getCode())
                .dailyRateReturn(new BigDecimal("0.012"))
                .threshold(new BigDecimal(5000))
                .build();

        List<TSubscribe> initData = List.of(usdo1, usdo7, usdo15, usdo30, talent, king, supreme);
        LambdaQueryWrapper<TSubscribe> subscribeQuery = new LambdaQueryWrapper<>();
        Long count = baseMapper.selectCount(subscribeQuery);
        if(count>=initData.size()){
            return true;
        }

        return super.saveBatch(initData);
    }

    @Override
    public List<SubscribeVO> all(){
        Long customerId = UserIdContext.getUserId();
        if(customerId==null){
            throw new BaseException(ErrorCode.UNAUTHORIZED);
        }
        LambdaQueryWrapper<TWallets> queryWallet = new LambdaQueryWrapper<>();
        queryWallet.eq(TWallets::getCustomerId, customerId);
        TWallets myWallet = tWalletMapper.selectOne(queryWallet);
        if(myWallet==null){
            throw new BaseException(ErrorCode.NOT_EXIST_WALLET);
        }

        List<TSubscribe> tSubscribes = super.list();
        if(CollectionUtils.isEmpty(tSubscribes)){
            throw new BaseException(ErrorCode.NOT_EXIST_SUBSCRIBE);
        }
        Map<String, TSubscribe> subscribeMap = tSubscribes.stream().collect(Collectors.toMap(TSubscribe::getSubscribeName, Function.identity()));
        TSubscribe dalent = subscribeMap.get(SubscribeNameEnum.SUBSCRIBE_DALENT.getCode());
        TSubscribe king = subscribeMap.get(SubscribeNameEnum.SUBSCRIBE_KING.getCode());
        TSubscribe supreme = subscribeMap.get(SubscribeNameEnum.SUBSCRIBE_SUPREME.getCode());

        LambdaQueryWrapper<TAppConfigItem> itemQuery = new LambdaQueryWrapper<>();
        List<TAppConfigItem> items = tAppConfigItemMapper.selectList(itemQuery);
        if(CollectionUtils.isEmpty(items)){
            throw new BaseException(ErrorCode.NOT_EXIST_CONFIG);
        }
        InitialGlobalConfig initialGlobalConfig = InitialGlobalConfig.instance();
        boolean subscribeShow = initialGlobalConfig.getSubscribeShowSpecial();
        if(!subscribeShow){
            tSubscribes.remove(dalent);
            tSubscribes.remove(king);
            tSubscribes.remove(supreme);
        }
        List<SubscribeVO> voList = new ArrayList<>(tSubscribes.stream().map(subscribe->{
            SubscribeVO vo = new SubscribeVO();
            BeanUtils.copyProperties(subscribe, vo);
            SubscribeNameEnum nameEnum = SubscribeNameEnum.byCode(subscribe.getSubscribeName());
            if(nameEnum!=null){
                vo.setSubscribeNameCn(nameEnum.getCn());
            }
            vo.setDailyRateReturn(subscribe.getDailyRateReturn().toPlainString());
            return vo;
        }).toList());
        return voList;
    }
}
